package nl.stroep.classbuilder.application 
{
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.net.FileReference;
	import flash.net.SharedObject;
	import mx.collections.ArrayList;
	import mx.containers.HDividedBox;
	import mx.controls.ProgressBar;
	import mx.core.ClassFactory;
	import mx.events.CollectionEvent;
	import nl.stroep.classbuilder.application.vo.ListItemVO;
	import nl.stroep.classbuilder.cb.CbClass;
	import nl.stroep.classbuilder.cb.CbMethod;
	import nl.stroep.classbuilder.cb.CbVariable;
	import nl.stroep.classbuilder.codeformatter.CodeFormatter;
	import nl.stroep.classbuilder.definitions.AccessModifiers;
	import nl.stroep.classbuilder.definitions.DataTypes;
	import nl.stroep.classbuilder.project.ProjectManager;
	import spark.components.DropDownList;
	import spark.components.List;
	import spark.components.TextArea;
	import spark.events.IndexChangeEvent;
	import spark.skins.spark.DefaultItemRenderer;
	/**
	 * ...
	 * @author Mark Knol
	 */
	
	[Bindable]
	public class Main extends HDividedBox
	{
		public var projectManager:ProjectManager; 
		
		public var projectsListData:ArrayList;
		public var classListData:ArrayList;
		public var variableListData:ArrayList;
		public var functionListData:ArrayList;
		
		public var codeView:TextArea;
		public var progressBar:ProgressBar;
		public var projectsDDL:DropDownList;
		public var classList:List;
		public var variableList:List;
		public var functionList:List;

		public var currentClass:CbClass;
		public var currentVariable:CbVariable;
		public var currentFunction:CbMethod;
		
		public function Main() 
		{
			this.addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			projectManager = ProjectManager.getInstance()
			projectManager.addEventListener(Event.COMPLETE, onProjectLoaded);
			projectManager.addEventListener(ProgressEvent.PROGRESS, onProjectProgress);
			projectManager.load();
			
			progressBar.setProgress( 0, 1 );
			
			variableListData.addEventListener(CollectionEvent.COLLECTION_CHANGE, refreshCodeView);
			functionListData.addEventListener(CollectionEvent.COLLECTION_CHANGE, refreshCodeView);
		}
		
		private function onProjectProgress(e:ProgressEvent):void 
		{
			progressBar.setProgress( Number(e.bytesLoaded / e.bytesTotal), 1 );
			progressBar.label = (e.bytesLoaded / e.bytesTotal).toString();
		}
		
		private function onProjectLoaded(e:Event):void 
		{	
			progressBar.label = null;
			
			projectsListData.addItem( { label:projectManager.current.name, data:projectManager.current.name } );
			
			currentClass = projectManager.current.classes[0];
			refreshAll();
			
			
			try { 
				projectsDDL.selectedIndex = projectManager.projects.indexOf(currentClass) + 1; 
				classList.selectedIndex = 0;
				variableList.selectedIndex = 0;
				functionList.selectedIndex = 0;
			}
			catch (e:*) 
			{
				
			}
		}
		
		protected function onProjectsListChange(event:IndexChangeEvent):void
		{
			var currentIndex:int = event.currentTarget.selectedIndex;
			projectManager.current = projectManager.projects[currentIndex];
			
			refreshAll();
			
			try { classList.selectedIndex = 0 } catch (e:*) { }
			
		}
		
		protected function onClassListChange(event:IndexChangeEvent):void
		{
			var classIndex:int = classListData.getItemAt(event.newIndex).data;
			currentClass = projectManager.current.classes[classIndex];
			
			refreshFunctions();
			refreshVariables();
			refreshCodeView();
			
			try { 
				variableList.selectedIndex = 0; 
				functionList.selectedIndex = 0; 
			}
			catch (e:*) 
			{
				
			}
		}
		
		protected function onFunctionListChange(event:IndexChangeEvent):void
		{
			trace(currentClass.functions[event.newIndex].name)
			currentFunction = currentClass.functions[event.newIndex];
		}
		
		protected function onVariableListChange(event:IndexChangeEvent):void
		{
			trace(currentClass.variables[event.newIndex].name)
			currentVariable = currentClass.variables[event.newIndex];
		}
		
		protected function list_itemRendererFunc(item:Object):ClassFactory 
		{
			var itemRenderer:Class = DefaultItemRenderer;
			
			switch (item.type) 
			{
				case VariableRenderer.TYPE:
					itemRenderer = VariableRenderer;
					break;
				
				case EditableRenderer.TYPE:
					itemRenderer = EditableRenderer;
					break;
					
					
				default:
					break;
			}
			return new ClassFactory(itemRenderer);
		}
		
		private function refreshCodeView(e:Event = null):void
		{
			codeView.text = CodeFormatter.format( currentClass.toString() );
		}
		
		private function refreshAll():void
		{
			refreshClasses();
			refreshVariables();
			refreshFunctions();
		}
		
		private function refreshClasses():void
		{
			classListData.removeAll();
			
			for (var i:uint = 0; i < projectManager.current.classes.length; ++i) 
			{
				var cbClass:CbClass = projectManager.current.classes[i];
				
				var c:ListItemVO = new ListItemVO()
				c.label = cbClass.name;
				c.data = i;
				c.cbObject = cbClass;
				c.type = VariableRenderer.TYPE;
				classListData.addItem( c );
				
				var j:uint;
				for (j = 0; j < cbClass.functions.length; ++j) 
				{
					var f:ListItemVO = new ListItemVO()
					f.label = cbClass.functions[j].name;
					f.data = i;
					f.cbObject = cbClass.functions[j]
					f.type = VariableRenderer.TYPE;
					classListData.addItem( f );
				}
				
				for (j = 0; j < cbClass.variables.length; ++j) 
				{
					var v:ListItemVO = new ListItemVO()
					v.label = cbClass.variables[j].name;
					v.data = i;
					v.cbObject = cbClass.variables[j]
					v.type = VariableRenderer.TYPE;
					classListData.addItem( v );
				}
			}
		}
		
		private function refreshVariables():void
		{
			variableListData.removeAll();
			
			for (var i:uint = 0; i < currentClass.variables.length; ++i) 
			{
				variableListData.addItem( {label: currentClass.variables[i].name, data:i, type:EditableRenderer.TYPE, cbObject: currentClass.variables[i]} );
			}
		}
		
		private function refreshFunctions():void
		{
			functionListData.removeAll();
			
			for (var i:uint = 0; i < currentClass.functions.length; ++i) 
			{
				functionListData.addItem( {label: currentClass.functions[i].name, data:i, type:EditableRenderer.TYPE, cbObject: currentClass.functions[i]} );
			}
		}

		protected function addFunction():void
		{
			var func:CbMethod = new CbMethod("myFunction", DataTypes.VOID);
			currentClass.functions.push(func);
			
			refreshAll();
		}
		
		protected function addVariable():void
		{
			var func:CbVariable = new CbVariable("myVar", DataTypes.STRING);
			currentClass.variables.push(func);
			
			refreshAll();
		}
		
		
		
	}

}